package cn.tyoui.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import cn.tyoui.commonenum.Coding;
import cn.tyoui.string.StringTools;
import cn.tyoui.tools.Tools;

/**
 * 常见的文件工具类
 * 
 * @author 张伟
 * @version 1.0
 *
 */
public class FileTools implements Tools {
	private static FileTools tools = null;
	private BufferedReader reader;
	private boolean blankFlag = true;
	private boolean isLine = true;
	private List<String> scanFile = new ArrayList<>();
	private String UTF_8 = Coding.UTF8.toString();

	public static FileTools initTool() {
		if (tools == null)
			return tools = new FileTools();
		return tools;
	}

	private FileTools() {
	}

	/**
	 * 生成文件对象
	 * 
	 * @param fileAddress
	 *            文件地址
	 * @return 文件对象
	 */
	public File getFile(String fileAddress) {
		File file = new File(fileAddress);
		if (file.exists())
			return file;
		return null;
	}

	/**
	 * 生成文件流对象。默认UTF-8编码
	 * 
	 * @param file
	 *            文件路径
	 * @return 文件流对象
	 */
	public BufferedReader createReader(String file) {
		return createReader(file, UTF_8);
	}

	/**
	 * 
	 * 生成文件(Reader)流对象
	 * 
	 * @param file
	 *            文件路径
	 * @param charsetName
	 *            字符串编码格式
	 * @return 文件流对象
	 */
	public BufferedReader createReader(String file, String charsetName) {
		try {
			return reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
		} catch (UnsupportedEncodingException | FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 关闭文件流
	 */
	public void closeReader() {
		try {
			if (reader != null)
				reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 输入流转化成缓冲流。默认UTF-8
	 * 
	 * @param inputStream
	 *            二进制输入流
	 * @return 缓冲流
	 */
	public BufferedReader inputStreamGetBufferReader(InputStream inputStream) {
		return inputStreamGetBufferReader(inputStream, UTF_8);
	}

	/**
	 * 输入流转化成缓冲流
	 * 
	 * @param inputStream
	 *            二进制输入流
	 * @param charset
	 *            文件格式
	 * @return 缓冲流
	 */

	public BufferedReader inputStreamGetBufferReader(InputStream inputStream, String charset) {
		BufferedReader bufferedReader = null;
		try {
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charset));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return bufferedReader;
	}

	/**
	 * 读取文件内容，默认字符编码UTF-8
	 * 
	 * @param file
	 *            读取文件
	 * @return 读取文件的内容
	 */
	public String readFile(String file) {
		return readFile(file, UTF_8);
	}

	/**
	 * 读取文件所有的数据
	 * 
	 * @param reader
	 *            缓冲文件对象
	 * @return 文件数据
	 */
	public String readFileAll(BufferedReader reader) {
		setReader(reader);
		StringBuilder builder = new StringBuilder();
		try {
			while (getReader().ready())
				builder.append(readLine(getReader()) + "\r\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
		closeReader();
		return builder.toString();
	}

	/**
	 * 读取文件内容,默认无过滤字符
	 * 
	 * @param file
	 *            读取文件
	 * @param charsetName
	 *            文件的字符编码
	 * @return 读取的内容
	 */
	public String readFile(String file, String charsetName) {
		return readFile(file, charsetName, null);
	}

	/**
	 * 读取文件，默认过滤文件一行无内容
	 * 
	 * @param file
	 *            文件路径
	 * @param charsetName
	 *            文件字符编码
	 * @param deleteCharset
	 *            过滤字符数组
	 * @return 过滤完毕的文件内容
	 */
	public String readFile(String file, String charsetName, String[] deleteCharset) {
		createReader(file, charsetName);
		StringBuilder builder = new StringBuilder((int) file.length() / 2);
		String str = null;
		while ((str = readLine(reader, isLine, blankFlag)) != null) {
			String date = StringTools.initTool().filterString(str, deleteCharset);
			if (date != null)
				builder.append(date);
		}
		return builder.toString();
	}

	/**
	 * 设置过滤一行无数据
	 * 
	 * @param blankFlag
	 *            是否过滤
	 */
	public void setBlankFlag(boolean blankFlag) {
		this.blankFlag = blankFlag;
	}

	/**
	 * 设置换行符
	 * 
	 * @param isLine
	 *            是否设置
	 */
	public void isLine(boolean isLine) {
		this.isLine = isLine;
	}

	/**
	 * 读取一行内容，默认有换行符
	 * 
	 * @param reader
	 *            读取的文件流
	 * @return 读取一行的数据
	 */
	public String readLine(BufferedReader reader) {
		return readLine(reader, true);
	}

	/**
	 * 读取一行内容，默认无过滤规则
	 * 
	 * @param reader
	 *            读取的文件流
	 * @param lineCharset
	 *            是否有换行符
	 * @return 返回一行的数据
	 */
	public String readLine(BufferedReader reader, boolean lineCharset) {
		return readLine(reader, lineCharset, false);
	}

	/**
	 * 读取一行数据，进行过滤判断
	 * 
	 * @param reader
	 *            文件流
	 * @param lineCharset
	 *            换行符
	 * @param filterblank
	 *            过滤一行无数据
	 * @return 一行数据
	 */
	public String readLine(BufferedReader reader, boolean lineCharset, boolean filterblank) {
		try {
			if (reader.ready()) {
				String line = reader.readLine();
				if (lineCharset) {
					if (filterblank && line.equals(""))
						return readLine(reader, lineCharset, filterblank);
					return line + "\r\n";
				}
				return line;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 遍历文件夹下的所有文件
	 * 
	 * @param dir
	 *            文件夹的名字
	 * @return 文件夹下的所有文件地址
	 */
	public List<String> scanDirectory(File dir) {
		File[] files = dir.listFiles();
		for (File f : files) {
			if (f.isDirectory())
				scanDirectory(f);
			else
				scanFile.add(f.getAbsolutePath());
		}
		return scanFile;
	}

	/**
	 * 删除链表中文件
	 * 
	 * @param listFile
	 *            链表文件
	 */
	public void deleteListFile(List<String> listFile) {
		for (String string : listFile) {
			File file = new File(string);
			if (file.exists())
				file.delete();
		}
	}

	/**
	 * 把文件每一行数据存取到链表中
	 * 
	 * @param fileName
	 *            文件地址
	 * @return 链表数据
	 */
	public List<String> LineReaderFile(String fileName) {
		List<String> list = new ArrayList<>();
		createReader(fileName);
		try {
			while (reader.ready())
				list.add(readLine(reader, false));
		} catch (Exception e) {
		}
		return list;
	}

	/**
	 * 获取文件流
	 * 
	 * @return 文件流
	 */
	public BufferedReader getReader() {
		return reader;
	}

	/**
	 * 获得二进制文件输入流
	 * 
	 * @param file
	 *            文件地址
	 * @return 文件输入流
	 */
	public InputStream getInputStream(String file) {
		if (file == null)
			return null;
		InputStream stream = null;
		try {
			stream = new BufferedInputStream(new FileInputStream(getFile(file)));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return stream;
	}

	/**
	 * 获得二进制文件输出流
	 * 
	 * @param file
	 *            文件
	 * @return 二进制文件输出对象
	 */
	public OutputStream getOutputStream(String file) {
		if (file == null)
			return null;
		OutputStream outputStream = null;
		try {
			outputStream = new BufferedOutputStream(new FileOutputStream(getFile(file)));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return outputStream;
	}

	/**
	 * 私有的对象类，不提供
	 * 
	 * @param reader
	 *            对象类
	 */
	private void setReader(BufferedReader reader) {
		this.reader = reader;
	}

}
